﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Serilog;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TMI85303.UI.Messages;
using TMI85303.Utils;

namespace TMI85303.UI.UserControls
{
    /// <summary>
    /// Reg168_169Control.xaml 的交互逻辑
    /// </summary>
    public partial class Reg168_169Control : UserControl
    {
        public Reg168_169Control()
        {
            InitializeComponent();
        }
    }

    public class Reg168_169ItemModel
    {
        public string? SerialNumber { get; set; }
        public string? Name { get; set; }
        public string? Description { get; set; }
    }

    public partial class Reg168_169VM : ObservableObject
    {
        public List<Reg168_169ItemModel> Reg168Bit0_Bit3andBit6 { get; set; } = new()
        {
            new() { SerialNumber = "-", Name = "Disable digital testmode", Description = "" },
            new() { SerialNumber = "0", Name = "FG", Description = "FG" },
            new() { SerialNumber = "1", Name = "OCL_CMP_Out", Description = "Over Current O/p from OCL  comp, Tests OCL Level or IPD-ZT levels" },
            new() { SerialNumber = "2", Name = "Bemf_CMP_Out", Description = "Raw BEMF Comparator O/p" },
            new() { SerialNumber = "3", Name = "ZeroAndNeg_Curr", Description = "" },
            new() { SerialNumber = "4", Name = "SYNC_OK", Description = "High: chip is ready to or already in sine mode" },
            new() { SerialNumber = "5", Name = "PosErr", Description = "phase advance adjustment feedback" },
            new() { SerialNumber = "6", Name = "NegErr", Description = "phase advance adjustment feedback" },
            new() { SerialNumber = "7", Name = "Bemf_Window", Description = "sine mode bemf window" },
            new() { SerialNumber = "8", Name = "BemfCMP_FILT", Description = "Filtered bemf comparator output" },
            new() { SerialNumber = "9", Name = "Bemf_Blank_TIME", Description = "blank ored with zero cross" },
            new() { SerialNumber = "10", Name = "DeadTime_A", Description = "for testing Phase A bridge delay" },
            new() { SerialNumber = "11", Name = "OCP_Faults", Description = "High or Low Side fault detected" },
            new() { SerialNumber = "12", Name = "OverVbbCMP_Sample", Description = "" },
            new() { SerialNumber = "13", Name = "IPD_ON_Window", Description = "High: IPD is active" },
            new() { SerialNumber = "14", Name = "IPD_SampPulse_H", Description = "Ipd sample pulse during initial zero torque" },
            new() { SerialNumber = "15", Name = "nFault", Description = "" },
        };

        public List<Reg168_169ItemModel> Reg168Bit7_Bit11 { get; set; } = new()
        {
            new() { SerialNumber = "-", Name = "Disable analog testmode", Description = "" },
            new() { SerialNumber = "0", Name = "空连接 (预留模拟信号通道)", Description = "" },
            new() { SerialNumber = "1", Name = "温度二极管输出电压", Description = "" },
            new() { SerialNumber = "2", Name = "1.2V基准电压", Description = "" },
            new() { SerialNumber = "3", Name = "VPP编程电压", Description = "" },
            new() { SerialNumber = "4", Name = "MTP基准电压", Description = "" },
            new() { SerialNumber = "5", Name = "温度传感器输出电流测试(需上拉)", Description = "" },
            new() { SerialNumber = "6", Name = "5V电源测试", Description = "" },
            new() { SerialNumber = "7", Name = "全局偏置电流测试(需下拉)", Description = "" },
            new() { SerialNumber = "8", Name = "时钟振荡器的偏置电流测试(需下拉)", Description = "" },
            new() { SerialNumber = "9", Name = "低侧门驱电源测试", Description = "" },
            new() { SerialNumber = "10", Name = "内部空连接", Description = "" },
            new() { SerialNumber = "11", Name = "OCL的电流检测输出电压", Description = "" },
            new() { SerialNumber = "12", Name = "OCL的REF电压", Description = "" },
            new() { SerialNumber = "13", Name = "ADC相关测试信号", Description = "" },
            new() { SerialNumber = "14", Name = "", Description = "" },
            new() { SerialNumber = "15", Name = "", Description = "" },
        };

        public List<Reg168_169ItemModel> Reg168Bit12_Bit14 { get; set; } = new()
        {
            new() { SerialNumber = "-", Name = "Disable these tests", Description = "" },
            new() { SerialNumber = "1", Name = "待ADC转换的模拟电压", Description = "" },
            new() { SerialNumber = "2", Name = "ADC电压基准 2.1V", Description = "" },
            new() { SerialNumber = "3", Name = "ADC电压基准 1.1V", Description = "" },
            new() { SerialNumber = "4", Name = "ADC电压基准 1.2V", Description = "" },
            new() { SerialNumber = "5", Name = "ADC 积分器输出电压", Description = "" },
            new() { SerialNumber = "6", Name = "电平转换过的积分器输出", Description = "" },
            new() { SerialNumber = "7", Name = "", Description = "" },
        };


        public List<Reg168_169ItemModel> Reg169 { get; set; } = new()
        {
            new() { SerialNumber = "-", Name = "Disable digital testmode", Description = "" },
            new() { SerialNumber = "0", Name = "FG", Description = "FG" },
            new() { SerialNumber = "1", Name = "VREF3.3V_OK", Description = "VDD Ok, Test: VDD UVLO Trip points" },
            new() { SerialNumber = "2", Name = "VBB_OK", Description = "VBB Ok, Test: VBB UVLO Trip points" },
            new() { SerialNumber = "3", Name = "TEMP_OK", Description = "Temperature Ok, Test: TSD Trip points" },
            new() { SerialNumber = "4", Name = "Test_PLLCLK", Description = "Test signal for looking at the PLL clock" },
            new() { SerialNumber = "5", Name = "OCL_CMP_Out", Description = "Over Current O/p from OCL  comp, Tests OCL Level or IPD-ZT levels" },
            new() { SerialNumber = "6", Name = "Reg5V_W35OK", Description = "" },
            new() { SerialNumber = "7", Name = "Reg5.3V_OK", Description = "" },
            new() { SerialNumber = "8", Name = "ADC_CMP_Out", Description = "ADC Comparator Output" },
            new() { SerialNumber = "9", Name = "BEMF_CMP_Out", Description = "BEMF Comparator O/p after first sync Reg" },
            new() { SerialNumber = "10", Name = "OverVBB_CMP_Out", Description = "VBB-Phase Comparator, after first sync Reg" },
            new() { SerialNumber = "11", Name = "VBB_OV", Description = "VBB over voltage" },
            new() { SerialNumber = "12", Name = "Start_Coast", Description = "High: start coasting" },
            new() { SerialNumber = "13", Name = "E_Freq_OK", Description = "" },
            new() { SerialNumber = "14", Name = "AngleCloseLoop", Description = "trigger output for Align Test or Spin Up Test/default output on TEST pin" },
            new() { SerialNumber = "15", Name = "ZeroAndNeg_Curr", Description = "" },
            new() { SerialNumber = "16", Name = "SCL_Test", Description = "external Pwm Input, Logic input level" },
            new() { SerialNumber = "17", Name = "SYNC_OK", Description = "High: chip is ready to or already in sine mode" },
            new() { SerialNumber = "18", Name = "(Sync_Error)", Description = "" },
            new() { SerialNumber = "19", Name = "PosErr", Description = "phase advance adjustment feedback" },
            new() { SerialNumber = "20", Name = "NegErr", Description = "phase advance adjustment feedback" },
            new() { SerialNumber = "21", Name = "BEMF_Window", Description = "sine mode bemf window" },
            new() { SerialNumber = "22", Name = "BemfCMP_FILT", Description = "Filtered bemf comparator output" },
            new() { SerialNumber = "23", Name = "BEMF_Check_EN", Description = "High: bemf comparator outputs are checked" },
            new() { SerialNumber = "24", Name = "DriveEnable", Description = "High: drive is enabled" },
            new() { SerialNumber = "25", Name = "Drive_On", Description = "High: drive is on" },
            new() { SerialNumber = "26", Name = "Fan_FastStartMode", Description = "High: fast mode" },
            new() { SerialNumber = "27", Name = "Bemf_Blank_TIME", Description = "blank ored with zero cross" },
            new() { SerialNumber = "28", Name = "DeadTime_A", Description = "for testing Phase A bridge delay" },
            new() { SerialNumber = "29", Name = "DeadTime__B", Description = "for testing Phase B bridge delay" },
            new() { SerialNumber = "30", Name = "DeadTime_C", Description = "for testing Phase C bridge delay" },
            new() { SerialNumber = "31", Name = "OCP_Faults", Description = "High or Low Side fault detected" },
            new() { SerialNumber = "32", Name = "Standby", Description = "High = in stanby mode" },
            new() { SerialNumber = "33", Name = "(MTP_TestStatus)", Description = "" },
            new() { SerialNumber = "34", Name = "PLLCLK_FBK", Description = "Signal from pll" },
            new() { SerialNumber = "35", Name = "(HalfVBB_CMP)(not used by logic)", Description = "" },
            new() { SerialNumber = "36", Name = "SDI_Test", Description = "Serial data input" },
            new() { SerialNumber = "37", Name = "nFault", Description = "nFault/default output on nFAULT pin" },
            new() { SerialNumber = "38", Name = "(MTP_LLAT)", Description = "" },
            new() { SerialNumber = "39", Name = "(MTP_HLAT)", Description = "" },
            new() { SerialNumber = "40", Name = "BEMF_HYS_EN", Description = "Bemf comparator hys enable" },
            new() { SerialNumber = "41", Name = "(MTP_ProctEn)", Description = "" },
            new() { SerialNumber = "42", Name = "(CP_OK)", Description = "" },
            new() { SerialNumber = "43", Name = "OCP_L_A", Description = "Low side fault from analog" },
            new() { SerialNumber = "44", Name = "OCP_L_B", Description = "Low side fault from analog" },
            new() { SerialNumber = "45", Name = "OCP_L_C", Description = "Low side fault from analog" },
            new() { SerialNumber = "46", Name = "OCP_H_A", Description = "High side fault from analog" },
            new() { SerialNumber = "47", Name = "OCP_H_B", Description = "High side fault from analog" },
            new() { SerialNumber = "48", Name = "OCP_H_C", Description = "High side fault from analog" },
            new() { SerialNumber = "49", Name = "OverVBB_CMP_Flt", Description = "VBB-Phase Comparator, after second sync Reg" },
            new() { SerialNumber = "50", Name = "OverVBB_Samp", Description = "Vbb comparator sampling pulse" },
            new() { SerialNumber = "51", Name = "Target_DIR", Description = "Motor Direction control from trim" },
            new() { SerialNumber = "52", Name = "ADCTimeUP_HalfOut", Description = "" },
            new() { SerialNumber = "53", Name = "ADC_TimeDown", Description = "" },
            new() { SerialNumber = "54", Name = "ADC_TimeUp", Description = "" },
            new() { SerialNumber = "55", Name = "Active_CMD", Description = "Pre driveEnable, without the debouncer delay" },
            new() { SerialNumber = "56", Name = "(trimRegOverRide )", Description = "" },
            new() { SerialNumber = "57", Name = "IPD_ON_Window", Description = "High: IPD is active" },
            new() { SerialNumber = "58", Name = "OverVBB_CMP_Latch", Description = "latched VBB comparator output (not used by logic)" },
            new() { SerialNumber = "59", Name = "IPD_SampPulse_H", Description = "Ipd sample pulse during initial zero torque" },
            new() { SerialNumber = "60", Name = "IPD_SampPulse_L", Description = "Ipd sample pulse during initial zero torque" },
            new() { SerialNumber = "61", Name = "", Description = "" },
            new() { SerialNumber = "62", Name = "", Description = "" },
            new() { SerialNumber = "63", Name = "", Description = "" },
        };


        [ObservableProperty]
        private int reg168Bit0_Bit3andBit6SelectIndex = 0;

        [ObservableProperty]
        private int reg168Bit7_Bit11SelectIndex = 0;

        [ObservableProperty]
        private int reg168Bit12_Bit14SelectIndex = 0;

        [ObservableProperty]
        private int reg169SelectIndex = 0;

        [ObservableProperty]
        private bool reg168Bit15Checked = false;

        [ObservableProperty]
        private bool reg169Bit0Checked = false;

        [ObservableProperty]
        private bool reg169Bit1Checked = false;

        [RelayCommand]
        private void WriteConfig168()
        {
            bool digitalSelected = Reg168Bit0_Bit3andBit6SelectIndex > 0;
            bool analogSelected = Reg168Bit7_Bit11SelectIndex > 0;
            int reg168Bit0_Bit3 = 0;
            int reg168Bit6 = 0;
            int reg168Bit7_Bit10 = 0;
            int reg168Bit11 = 0;
            int reg168Bit15 = 0;


            if (digitalSelected && analogSelected)
            {
                MessageBox.Show("Please select either a digital OR analog testmode - both are selected.");
                return;
            }

            if (analogSelected)
            {
                Log.Information(" Enabling testmode with bit 15 of reg 166\r\n");
                WeakReferenceMessenger.Default.Send<UpdateRegValue, int>(new(166,15,1), (int)MesgToken.Reg166Token);
                int writeData = ReadWrite.ReadReg(166, 2) | 0x8000;
                ReadWrite.WriteReg(166, writeData, 2);
            }
            checked
            {
                if (Reg168Bit15Checked)
                {
                    reg168Bit15 = 1;
                }

                if (digitalSelected)
                {
                    reg168Bit6 = 1;
                    reg168Bit0_Bit3 = Reg168Bit0_Bit3andBit6SelectIndex - 1;
                }

                if (analogSelected)
                {
                    reg168Bit11 = 1;
                    reg168Bit7_Bit10 = Reg168Bit7_Bit11SelectIndex - 1;
                }

                int reg168Bit12_Bit14 = Reg168Bit12_Bit14SelectIndex;

                int writeData168 = (reg168Bit15 << 15) | (reg168Bit12_Bit14 << 12) | (reg168Bit11 << 11) |
                               (reg168Bit7_Bit10 << 7) | (reg168Bit6 << 6) | reg168Bit0_Bit3;

                ReadWrite.WriteReg(168, writeData168, 2);
            }
        }

        [RelayCommand]
        private void ClearConfig168() => ReadWrite.WriteReg(168, 0, 2);

        [RelayCommand]
        private void WriteConfig169()
        {
            int reg169Bit0 = Reg169Bit0Checked ? 1 : 0;
            int reg169Bit1 = Reg169Bit1Checked ? 1 : 0;
            int reg169Bit2 = Reg169SelectIndex > 0 ? 1 : 0;
            int reg169Bit3_Bit8 = Math.Max(0, Reg169SelectIndex - 1);
            int writeData169 = (reg169Bit3_Bit8 << 3) | (reg169Bit2 << 2) | (reg169Bit1 << 1) | reg169Bit0;
            ReadWrite.WriteReg(169, writeData169, 2);
        }

        [RelayCommand]
        private void ClearConfig169() => ReadWrite.WriteReg(169, 0, 2);

    }
}
